const blockImagesPath = ['/images/planewar/basketball_enemy.png', '/images/planewar/football_enemy.png', '/images/planewar/soccer_enemy.png']

const swapTime = 200    // ms

Page({
  data: {
    blockSize: 50,
    rows: 6,
    cols: 6,
    canvasWidth: 300,
    canvasHeight: 300,
    gridSize: 6,
    // blockTypes: ['red', 'blue', 'green', 'yellow'],
    blockImages : [],
    grid: [],
    blockWidth: 0,
    blockHeight: 0,
    score: 0,
    ctx: null, // 添加上下文属性
    canvas:null,

    selectedBlock: null,
    destBlock: null,
    moveStartTime: 0,
    startX: 0,
    startY: 0,
    endX: 0,
    endY: 0,
    direction:null,
    isAnimating: false,  // 是否正在播放动画
  },
  loadImage(callback){

    let enemyCount = 0

    let checkAllOver = ()=>{
      if (enemyCount == blockImagesPath.length){
        this.data.load_over = true
        callback()
      }
    }
    for (var i=0;i<blockImagesPath.length;i++){
      const img = this.data.canvas.createImage()
      img.onload = () => {
        this.data.blockImages.push(img)
        enemyCount++
        checkAllOver()
      }
      img.src = blockImagesPath[i]
    }
  },

  onLoad() {
      const query = wx.createSelectorQuery();
      query.select('#gameCanvas').fields({ node: true, size: true, rect: true }).exec(res => {
        const canvas = res[0].node;
        const ctx = canvas.getContext('2d');
  
        const width = res[0].width;
        const height = res[0].height;
  
        const canvasOffsetX = res[0].left;
        const canvasOffsetY = res[0].top;
  
        console.log("res", res)
  
        const dpr = wx.getSystemInfoSync().pixelRatio
        canvas.width = width * dpr
        canvas.height = height * dpr
        ctx.scale(dpr, dpr)
  
        console.log("onLoad", width, height, dpr)
  
        this.setData({
          canvasWidth: width,
          canvasHeight: height,
          canvasOffsetX: canvasOffsetX,
          canvasOffsetY: canvasOffsetY,
          blockWidth: width / this.data.gridSize,
          blockHeight: height / this.data.gridSize,
          ctx: ctx, // 保存上下文引用
          canvas:canvas,
        });
        this.loadImage(res=>{
          this.initGame();
          const renderLoop = () => {
            this.drawGame();
            canvas.requestAnimationFrame(renderLoop)
          }
          canvas.requestAnimationFrame(renderLoop)
        })
      });
  },

  initGame() {
    const { gridSize, blockImages } = this.data;
    const grid = [];

    for (let i = 0; i < gridSize; i++) {
      grid[i] = [];
      for (let j = 0; j < gridSize; j++) {
        grid[i][j] = blockImages[Math.floor(Math.random() * blockImages.length)];
      }
    }

    this.setData({ grid });
  },

  drawGame() {

    let currentTime = Date.now();
    let deltaTime = currentTime - this.lastFrameTime || 0;
    this.lastFrameTime = currentTime;

    const { canvasWidth, canvasHeight, gridSize, grid, blockWidth, blockHeight, ctx, selectedBlock, destBlock, moveStartTime } = this.data;

    ctx.clearRect(0, 0, canvasWidth, canvasHeight);

    for (let i = 0; i < gridSize; i++) {
      for (let j = 0; j < gridSize; j++) {
        let blockX = j * blockWidth;
        let blockY = i * blockHeight;

        let deltaX = 0, deltaY = 0

        if (selectedBlock && destBlock){   // 500ms播完 1ms移动 blockWidth/500
          if (selectedBlock.row == i && selectedBlock.col == j){
            deltaX = (destBlock.col - selectedBlock.col) * blockWidth / swapTime * (currentTime - moveStartTime)
            deltaY = (destBlock.row - selectedBlock.row) * blockWidth / swapTime * (currentTime - moveStartTime)

            if (Math.abs(deltaX) >= blockWidth || Math.abs(deltaY) >= blockHeight){
              let temp = grid[i][j] 
              grid[i][j] = grid[destBlock.row][destBlock.col]
              grid[destBlock.row][destBlock.col] = temp
              this.moveGridEnd()
              deltaX = 0
              deltaY = 0
            }

          }else if(destBlock.row == i && destBlock.col == j){
            deltaX = (selectedBlock.col - destBlock.col)  * blockWidth / swapTime * (currentTime - moveStartTime)
            deltaY = (selectedBlock.row - destBlock.row)  * blockWidth / swapTime * (currentTime - moveStartTime)
          }
        }
        ctx.drawImage(grid[i][j], blockX + deltaX, blockY + deltaY, blockWidth, blockHeight);
      }
    }
  },

  getGridIndex(canvasX, canvasY) {
    const { blockWidth, blockHeight, canvasOffsetX, canvasOffsetY } = this.data;

    // 将事件坐标转换为相对于 canvas 左上角的坐标
    const canvasXRelativeToCanvas = canvasX - canvasOffsetX;
    const canvasYRelativeToCanvas = canvasY - canvasOffsetY;

    // 计算 grid 中的索引
    const gridX = Math.floor(canvasXRelativeToCanvas / blockWidth);
    const gridY = Math.floor(canvasYRelativeToCanvas / blockHeight);

    return { x: gridX, y: gridY };
  },

  getDirection(){
    let direction;
    let deltaX = this.data.endX - this.data.startX;
    let deltaY = this.data.endY - this.data.startY;
    if (Math.abs(deltaX) > Math.abs(deltaY)) {
      direction = deltaX > 0 ? 'right' : 'left';
    } else {
      direction = deltaY > 0 ? 'down' : 'up';
    }
    return direction
  },

  moveGridAnim(){
    let {row,col} = this.data.selectedBlock
    let destBlock = {row, col}
    if (this.data.direction == "up"){
      if (row > 0){
        destBlock.row--
      }
    }else if(this.data.direction == "down"){
      if (row < this.data.rows - 1){
        destBlock.row++
      }
    }else if(this.data.direction == "left"){
      if (col > 0){
        destBlock.col--
      }
    }else if(this.data.direction == "right"){
      if (col < this.data.cols - 1){
        destBlock.col++
      }
    }
    this.setData({isAnimating:true, destBlock, moveStartTime: Date.now()})
  },

  moveGridEnd(){
    let {selectedBlock, destBlock, back} = this.data
    if (back){
      this.setData({back:false, isAnimating:false, })
      return
    }
    let isMatch = this.checkMatches()
    console.log("moveGridEnd", isMatch)
    if (!isMatch){    // 弹回去
      let temp = selectedBlock
      selectedBlock = destBlock
      destBlock = temp
      this.setData({isAnimating:true, moveStartTime: Date.now(), back: true})
    }
    this.setData({selectedBlock:null, destBlock:null, isAnimating:false})
  },

  // 处理触摸开始事件
  handleTouchStart: function(event) {
    if (this.data.isAnimating) return;  // 如果正在播放动画，则忽略触摸事件
    let selectedBlock = this.getBlockAtTouch(event.touches[0].clientX, event.touches[0].clientY);
    if (selectedBlock) {
      this.setData({
        selectedBlock,
        startX: event.touches[0].clientX,
        startY: event.touches[0].clientY,
      });
    }
    console.log("handleTouchStart", event, "selectedBlock", selectedBlock)
  },

  // 处理触摸移动事件
  handleTouchMove: function(event) {
    if (this.data.isAnimating || !this.data.selectedBlock) return;  // 如果正在播放动画或未选中方块，则忽略触摸事件
    this.setData({
      endX: event.touches[0].clientX,
      endY: event.touches[0].clientY
    });
    if (!this.data.direction){
      this.setData({direction:this.getDirection()})
      this.moveGridAnim()   // 开始播滑动动画
    }
    console.log("handleTouchMove", event)
  },

  // 处理触摸结束事件
  handleTouchEnd: function(event) {
    // if (this.data.isAnimating || !this.data.selectedBlock) return;  // 如果正在播放动画或未选中方块，则忽略触摸事件
    // // let direction = this.getDirection()
    // this.handleSwipe(this.data.direction);
    // this.setData({direction:null})
  },

  // 处理滑动事件
  handleSwipe: function(direction) {
    let selectedBlock = this.data.selectedBlock;
    let targetBlock;
    switch (direction) {
      case 'up':
        targetBlock = { row: selectedBlock.row - 1, col: selectedBlock.col };
        break;
      case 'down':
        targetBlock = { row: selectedBlock.row + 1, col: selectedBlock.col };
        break;
      case 'left':
        targetBlock = { row: selectedBlock.row, col: selectedBlock.col - 1 };
        break;
      case 'right':
        targetBlock = { row: selectedBlock.row, col: selectedBlock.col + 1 };
        break;
    }
    if (targetBlock && this.isAdjacent(targetBlock, selectedBlock)) {
      this.swapBlocks(targetBlock, selectedBlock);
      this.checkMatches();
    }
    this.setData({ selectedBlock: null, direction:null });
  },

  // 获取触摸点对应的方块坐标
  getBlockAtTouch: function(x, y) {
    let row = Math.floor(y / this.data.blockSize);
    let col = Math.floor(x / this.data.blockSize);
    if (row >= 0 && row < this.data.rows && col >= 0 && col < this.data.cols) {
      return { row, col };
    }
    return null;
  },

  // 判断两个方块是否相邻
  isAdjacent: function(block1, block2) {
    return (Math.abs(block1.row - block2.row) + Math.abs(block1.col - block2.col)) === 1;
  },

  // 交换两个方块
  swapBlocks: function(block1, block2) {
    let grid = this.data.grid;
    let temp = grid[block1.row][block1.col];
    grid[block1.row][block1.col] = grid[block2.row][block2.col];
    grid[block2.row][block2.col] = temp;
    this.setData({ grid });
    console.log("swapBlocks", block1, block2)
  },

  // 检查是否有连续的方块组合
  checkMatches: function() {
    let grid = this.data.grid;
    let matches = [];
    for (let row = 0; row < this.data.rows; row++) {
      for (let col = 0; col < this.data.cols; col++) {
        let blockType = grid[row][col];
        if (blockType === -1) continue;
        // 检查水平方向
        if (col < this.data.cols - 2 && grid[row][col + 1] === blockType && grid[row][col + 2] === blockType) {
          matches.push({ row, col }, { row, col: col + 1 }, { row, col: col + 2 });
        }
        // 检查垂直方向
        if (row < this.data.rows - 2 && grid[row + 1][col] === blockType && grid[row + 2][col] === blockType) {
          matches.push({ row, col }, { row: row + 1, col }, { row: row + 2, col });
        }
      }
    }
    if (matches.length > 0) {
      this.setData({ isAnimating: true });
      this.removeBlocks(matches);
      this.dropBlocks()
      return true
    }
    return false
  },

  // 移除匹配的方块
  removeBlocks: function(matches) {
    let grid = this.data.grid;
    for (let match of matches) {
      grid[match.row][match.col] = null;
    }
    this.setData({ grid });
    setTimeout(() => {
      this.setData({ isAnimating: false });
    }, 500);  // 假设动画时长为0.5秒
  },

  dropBlocks() {
    // 方块下落
    const { grid, gridSize } = this.data;

    for (let x = 0; x < gridSize; x++) {
      let fallDistance = 0;
      for (let y = gridSize - 1; y >= 0; y--) {
        if (!grid[y][x]) {
          // 如果方块为空，则继续向上搜索非空方块
          for (let k = y - 1; k >= 0; k--) {
            if (grid[k][x]) {
              // 找到非空方块，进行下落
              grid[y][x] = grid[k][x];
              grid[k][x] = null;
              fallDistance++;
              break;
            }
          }
        }
      }
      // 如果有方块下落，则等待下落动画完成后继续消除
      if (fallDistance > 0) {
        setTimeout(() => {
          this.dropBlocks();
        }, fallDistance * 500); // 下落速度，可调整
        break;
      }
    }

    // 填补空缺
    this.fillEmptyBlocks();
  },

  fillEmptyBlocks() {
    // 填补空缺
    const { grid, gridSize, blockImages } = this.data;

    for (let y = gridSize - 1; y >= 0; y--) {
      for (let x = 0; x < gridSize; x++) {
        if (!grid[y][x]) {
          // 如果方块为空，则随机生成一个新方块填充
          grid[y][x] = blockImages[Math.floor(Math.random() * blockImages.length)];
        }
      }
    }

    // 继续消除
    setTimeout(() => {
      this.drawGame();
      this.checkGameOver();
    }, 200); // 填充速度，可调整
  },

  checkGameOver() {
    // 检查游戏是否结束
    const { grid, gridSize } = this.data;
    let gameOver = true;

    for (let y = 0; y < gridSize; y++) {
      for (let x = 0; x < gridSize; x++) {
        if (grid[y][x]) {
          // 如果有非空方块，则游戏未结束
          gameOver = false;
          break;
        }
      }
      if (!gameOver) break;
    }

    if (gameOver) {
      // 游戏结束逻辑
      console.log('游戏结束');
    }
  }
});
